﻿/*=================================================
*FileName:      SaveNguiTexture.cs 
*Author:        None 
*UnityVersion:  2021.2.18f1 
*Date:          2025-07-29 13:37 
*Description:   
*History:       
=================================================*/

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEditor;

public class SaveNguiTexture : Editor
{
    private static string modePath = "Assets/Model/Monster";
    [MenuItem("Assets/批量导出图集单图AtlasTextures")]
    static void DoCutTextures()
    {
        string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab", new[] { modePath });
        int totalCount = prefabGuids.Length;
        for (int i = 0; i < totalCount; i++)
        {
            // 检查用户是否取消
            if (EditorUtility.DisplayCancelableProgressBar("批量导出图集单图", $"Step {i}/{totalCount}", i / totalCount))
            {
                break;
            }
            
            string path = AssetDatabase.GUIDToAssetPath(prefabGuids[i]);
            UIAtlas atlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(path);
            if (atlas == null)
            {
                UnityEngine.Debug.LogError($"不是图集 {path}");
                continue;
            }

            CutTextures(atlas, Application.dataPath + "/Monster/" + atlas.name);
        }
        
        AssetDatabase.Refresh();
        EditorUtility.ClearProgressBar();
    }
    
    
    [MenuItem("Assets/导出图集单图AtlasTextures")]
    static void Do()
    {
        string[] selectedAssets = Selection.assetGUIDs;
        if (selectedAssets == null || selectedAssets.Length == 0) return;
        foreach (string guid in selectedAssets)
        {
            string path = AssetDatabase.GUIDToAssetPath(guid);
            UIAtlas atlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(path);
            if (atlas == null)
            {
                UnityEngine.Debug.LogError($"不是图集 {path}");
                continue;
            }

            CutTextures(atlas, Application.dataPath + "/AtlasTextures/" + atlas.name);
        }

        AssetDatabase.Refresh();
        EditorUtility.ClearProgressBar();
    }

    static List<UIAtlasMaker.SpriteEntry> spriteEntrys = new List<UIAtlasMaker.SpriteEntry>(20);
    /// <summary>
    /// 将图集中的所有图片拆分并保存
    /// </summary>
    /// <param name="_atlas">图集</param>
    /// <param name="_refresh">是否立即更新</param>
    public static bool CutTextures(UIAtlas _atlas, string folderPath)
    {
        // 验证参数有效性
        if (_atlas.texture == null)
        {
            UnityEngine.Debug.LogError($"没有图片引用 {_atlas.name}");
            return false;
        }

        if (!Directory.Exists(folderPath))
        {
            Directory.CreateDirectory(folderPath);
            // AssetDatabase.Refresh();
        }
        else
        {
            return true;
        }
        
        spriteEntrys.Clear();
        UIAtlasMaker.ExtractSprites(_atlas, spriteEntrys);

        if (spriteEntrys.Count == 0)
        {
            UnityEngine.Debug.LogError($"图集中没有图片 {_atlas.name}");
            return false;
        }
        
        int firstHeight = 0;
        for (int i = 0; i < spriteEntrys.Count; i++)
        {
            var se = spriteEntrys[i];
            if (se == null) continue;

            if (i == 0) firstHeight = se.height / 2;
            
            string path = folderPath + "/" + Regex.Replace(se.name.Split('_')[^1], @"^0+(?!$)", "") + ".png";

            SaveSpriteAsTexture(se, firstHeight, path);
        }

        return true;
    }
    
    /// <summary>
    /// 保存图集中的图片
    /// </summary>
    /// <param name="_atlas">图片所在的图集</param>
    /// <param name="_sprite">图集中要保存的图片名字</param>
    /// <param name="_path">要保存的路径</param>
    public static void SaveSpriteAsTexture(UIAtlasMaker.SpriteEntry se, int firstHeight, string _path)
    {
        if (se != null)
        {
            var targetTex = PadToSquare(se.tex, se, firstHeight);
            byte[] bytes = targetTex.EncodeToPNG();
            
            File.WriteAllBytes(_path, bytes);
            // AssetDatabase.ImportAsset(_path);
            // if (se.temporaryTexture)
            DestroyImmediate(se.tex);
            DestroyImmediate(targetTex);
        }
    }

    public static Texture2D PadToSquare(Texture2D src, UISpriteData sd, int firstHeight, int targetSize = 512)
    {
        //图像宽高
        int srcW = src.width;
        int srcH = src.height;

        //原数据画布宽高
        int sourceW = sd.paddingLeft + sd.width + sd.paddingRight;
        int sourceH = sd.paddingTop + sd.height + sd.paddingBottom;

        // 1. 计算偏移
        int offsetX = (targetSize - sourceW) / 2 + sd.paddingLeft;
        if (offsetX < 0) offsetX = sd.paddingLeft;

        int offsetY = (targetSize - sourceH) / 2 + sd.paddingBottom + firstHeight;
        if (offsetY < 0) offsetY = sd.paddingBottom;

        int changeTargetSize = targetSize;
        // //2.判断是否超出画布，超出需要动态调整画布大小
        if (offsetY + srcH > targetSize)
        {
            changeTargetSize = Mathf.Max(sourceH, targetSize) + firstHeight;
        }

        if (offsetX + srcW > changeTargetSize)
        {
            changeTargetSize = sourceW;
        }

        if (changeTargetSize > targetSize)
        {
            targetSize = changeTargetSize;
            //重新计算偏移
            offsetX = (targetSize - sourceW) / 2 + sd.paddingLeft;
            if (offsetX < 0) offsetX = sd.paddingLeft;

            offsetY = (targetSize - sourceH) / 2 + sd.paddingBottom + firstHeight;
            if (offsetY < 0) offsetY = sd.paddingBottom;
        }
        
        // 3. 创建目标 512×512 纹理
        Texture2D dst = new Texture2D(targetSize, targetSize, TextureFormat.RGBA32, false);
        
        // 4. 先全部透明
        Color[] fill = Enumerable.Repeat(Color.clear, targetSize * targetSize).ToArray();
        dst.SetPixels(fill);
        
        // int sourceW = sd.paddingLeft + sd.width + sd.paddingRight;
        // int sourceH = sd.paddingTop + sd.height + sd.paddingBottom;
        //
        // // 1. 创建目标 512×512 纹理
        // Texture2D dst = new Texture2D(sourceW, sourceH, TextureFormat.RGBA32, false);
        //
        // // 2. 先全部透明
        // Color[] fill = Enumerable.Repeat(Color.clear, sourceW * sourceH).ToArray();
        // dst.SetPixels(fill);
        //
        // // 3. 计算新的偏移
        // int offsetX = sd.paddingLeft;
        // int offsetY = sd.paddingBottom;// + firstHeight;

        // 4. 逐像素拷贝原图
        Color[] srcPixels = src.GetPixels();
        for (int y = 0; y < srcH; y++)
        {
            for (int x = 0; x < srcW; x++)
            {
                dst.SetPixel(offsetX + x, offsetY + y, srcPixels[y * srcW + x]);
            }
        }

        dst.Apply();
        return dst;
    }
}